package com.grace.cms.general.service.impl;

import java.io.File;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.ArrayList;
import java.util.List;
import org.apache.commons.io.FilenameUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.config.YamlMapFactoryBean;
import org.springframework.core.io.FileSystemResource;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;
import com.alibaba.fastjson2.JSONObject;
import com.grace.cms.common.enums.properties.OlyThemeConfigProperties;
import com.grace.cms.common.model.support.ThemeTreeNode;
import com.grace.cms.common.utils.ZipUtils;
import com.grace.cms.general.service.IWebThemeService;
import com.grace.cms.general.utils.WebUtils;
import com.grace.common.enums.GraceServerRoot;
import com.grace.common.exception.ServiceException;
import com.grace.common.exception.file.FileSizeLimitExceededException;
import com.grace.common.exception.file.InvalidExtensionException;
import com.grace.common.utils.StringUtils;
import com.grace.common.utils.file.FileUtils;
import com.grace.common.utils.file.MimeTypeUtils;
import com.grace.storage.enums.PrefixTypeEnums;
import com.grace.storage.service.impl.NativeStorageHandler;

@Service
public class WebThemeServiceImpl implements IWebThemeService {

    @Autowired
    private NativeStorageHandler storageHanded;

    @Override
    public boolean deleteThemeByName(String themeName) throws FileNotFoundException {

        return WebUtils.deleteThemeFile(themeName);
    }

    @Override
    public boolean uploadTheme(MultipartFile file, boolean cover, String themeName)
            throws IOException, FileSizeLimitExceededException, InvalidExtensionException {
        File alreadyUpload = Paths
                .get(GraceServerRoot.THEME_DIR.getWorkRoot(themeName))
                .toFile();

        // 是否已经上传过
        if (alreadyUpload.exists() && !cover) {
            throw new ServiceException("主题已经上传,你选择的不是覆盖上传,主题安装终止!");
        }

        // xxx.xx
        String fileName = FilenameUtils.getName(file.getOriginalFilename());
        storageHanded.storageAppointUpload(file, GraceServerRoot.THEME_DIR, fileName, MimeTypeUtils.COMPRESS_EXTENSION,
                PrefixTypeEnums.COVER, false);
        // 主题文件 路径/xx/themes/themeName.zip
        File themeFile = Paths.get(GraceServerRoot.THEME_DIR.getWorkRoot(fileName)).toFile();
        // 解压到当前目录 themeFile.getParent() /themes
        ZipUtils.unZipFilesAppoint(themeFile.getAbsolutePath(), themeFile.getParent());
        // 删除压缩文件
        return ZipUtils.deleteDir(themeFile.getAbsoluteFile());
    }

    /**
     * 读取配置文件
     */
    @Override
    public Object selectThemeConfigSetting(String themeName) {
        File themeYaml = Paths
                .get(GraceServerRoot.THEME_DIR.getWorkRoot(themeName), GraceServerRoot.THEME_TEMPLATE_DIR.getValue(),
                        OlyThemeConfigProperties.THEME_INFO.defaultValue())
                .toFile();
        if (themeYaml.exists() && !themeYaml.isDirectory()) {
            YamlMapFactoryBean yamMap = new YamlMapFactoryBean();
            FileSystemResource fileResource = new FileSystemResource(themeYaml);
            yamMap.setResources(fileResource);
            return yamMap.getObject();
        } else {
            throw new ServiceException("获取主题说明异常");
        }
    }

    @Override
    public Object selectThemeConfigForm(String themeName) throws IOException {
        String jsonString = FileUtils.readFileContent(Paths
                .get(GraceServerRoot.THEME_DIR.getWorkRoot(themeName), GraceServerRoot.THEME_TEMPLATE_DIR.getValue(),
                        OlyThemeConfigProperties.THEME_CONFIG_FORM.defaultValue()));
        JSONObject jsonObject = JSONObject.parseObject(jsonString);
        return jsonObject;
    }

    @Override
    public List<ThemeTreeNode> selectThemeFileTree(String path) {
        if (StringUtils.isEmpty(path)) {
            path = "";
        }
        List<ThemeTreeNode> themeTreeNodes = new ArrayList<>();
        // 获取主题路径
        final File themesPath = new File(GraceServerRoot.THEME_DIR.getWorkRoot());
        listFile(themesPath, path, themeTreeNodes);
        return themeTreeNodes;

    }

    /**
     * 遍历主题文件
     * 
     * @param dir
     * @param prefix
     * @param themeList
     */
    private void listFile(File dir, String prefix, List<ThemeTreeNode> themeList) {
        File[] files = dir.listFiles();
        if (null != files) {
            for (File file : files) {
                ThemeTreeNode themeTreeNode = new ThemeTreeNode();
                themeTreeNode.setpId(prefix);
                themeTreeNode.setId(prefix + "/" + file.getName());
                themeTreeNode.setName(file.getName());
                if (file.isDirectory()) {
                    themeTreeNode.setParent(file.isDirectory());
                    themeTreeNode.setChildren(new ArrayList<>());
                    listFile(file, prefix + "/" + file.getName(), themeTreeNode.getChildren());
                }
                themeList.add(themeTreeNode);
            }
        }
    }

    @Override
    public ThemeTreeNode buildThemeFile(String themeName) {
        ThemeTreeNode themeRoot = new ThemeTreeNode();
        themeRoot.setpId("/");
        themeRoot.setId("/" + themeName);
        themeRoot.setName(themeName);
        themeRoot.setParent(true);
        ThemeTreeNode themeRootTempalte = new ThemeTreeNode();
        themeRootTempalte.setpId("/" + themeName);
        themeRootTempalte.setId("/" + themeName + "/templates");
        themeRootTempalte.setName("templates");
        themeRootTempalte.setParent(true);
        themeRootTempalte.setChildren(new ArrayList<>());
        Path templatePath = Paths.get(GraceServerRoot.THEME_DIR.getWorkRoot(), themeName,GraceServerRoot.THEME_TEMPLATE_DIR.getValue() );
        listFile(templatePath.toFile(),  themeName+"/templates", themeRootTempalte.getChildren());
        ThemeTreeNode themeRootStatic = new ThemeTreeNode();
        themeRootStatic.setpId("/" + themeName);
        themeRootStatic.setId("/" + themeName + "/static");
        themeRootStatic.setName("static");
        themeRootStatic.setParent(true);
        themeRootStatic.setChildren(new ArrayList<>());
        Path staticPath = Paths.get(GraceServerRoot.THEME_DIR.getWorkRoot(), themeName, GraceServerRoot.THEME_STATIC_DIR.getValue());
        listFile(staticPath.toFile(),"/"+themeName+ "/static", themeRootStatic.getChildren());
        themeRoot.setChildren(new ArrayList<ThemeTreeNode>() {
            {
                add(themeRootStatic);
                add(themeRootTempalte);
            }
        });
        return themeRoot;
    }

}
